package com.thinkfit.jy.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Looper;

import androidx.core.app.ActivityCompat;

import com.common.lib.utils.LogUtil;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

public class ProjectionScreenUtils {

    private static ProjectionScreenUtils projectionScreenUtils;

    static List<WifiP2pDevice> list;

    WifiP2pManager wifiP2pManager;

    WifiP2pManager.Channel channel;

    private boolean mIsStart = false;

    MyReceiver myReceiver;
    Context mContext;

    public static ProjectionScreenUtils getInstance() {
        if (projectionScreenUtils == null) {
            projectionScreenUtils = new ProjectionScreenUtils();
        }
        return projectionScreenUtils;
    }

    public void init(Context context) {
        if (mIsStart) {
            return;
        }
        mContext = context;
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(context, Manifest.permission.NEARBY_WIFI_DEVICES)
                != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }

        wifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
        channel = wifiP2pManager.initialize(context, Looper.getMainLooper(), null);
        setEnableWFD(wifiP2pManager, channel, true, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                LogUtil.LogE("Successfully enabled WFD.");
            }

            @Override
            public void onFailure(int reason) {
                LogUtil.LogE("Failed to enable WFD with reason " + reason + ".");
            }
        });

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
        myReceiver = new MyReceiver();
        context.registerReceiver(myReceiver, intentFilter);

        wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {

            }

            @Override
            public void onFailure(int i) {

            }
        });

        startDiscovery();
    }

    public void stop() {
        if (mIsStart) {
            LogUtil.LogE("stop miraCast discovery.");
            stopDiscovery();
            wifiP2pManager.removeGroup(channel, null);
            mContext.unregisterReceiver(myReceiver);
//            mIsMiraCastMgrStop = true;
            mIsStart = false;

//            if (wifiP2PIsConnected) {
//                wifiP2PIsConnected = false;
//                mIsGroupFormed = false;
//                LogUtil.LogE("wifiP2P Disconnected");
//                mOnMirrorListener.onSessionEnd();
//            }
        }
    }

    public static class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION:
                    System.out.println("ddddddddddddddddddddddd   WIFI_P2P_STATE_CHANGED_ACTION ");
                    boolean p2pIsEnable = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED;
                    break;
                case WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION:
                    System.out.println("ddddddddddddddddddddddd   WIFI_P2P_PEERS_CHANGED_ACTION ");
                    //获取到设备列表信息
                    WifiP2pDeviceList mPeers = intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
                    list.clear(); //清除旧的信息
                    list.addAll(mPeers.getDeviceList()); //更新信息
//                    adapter.notifyDataSetChanged();  //更新列表

                    break;
                case WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION:
                    System.out.println("ddddddddddddddddddddddd   WIFI_P2P_CONNECTION_CHANGED_ACTION ");
                    NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
                    WifiP2pInfo wifiP2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
                    WifiP2pGroup wifiP2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
                    break;
                case WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:
                    System.out.println("ddddddddddddddddddddddd   WIFI_P2P_THIS_DEVICE_CHANGED_ACTION ");
                    WifiP2pDevice device = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
//                    deviceInfo.setText(getString(R.string.device_info) + device.deviceName );
                    break;
                case WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION:
                    System.out.println("ddddddddddddddddddddddd   WIFI_P2P_DISCOVERY_CHANGED_ACTION ");
                    int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
//                    isDiscover = discoveryState == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED;
//                    updateState();
                    break;
            }
        }
    }

    public void unregisterReceiver() {
        if (myReceiver != null) {
            mContext.unregisterReceiver(myReceiver);
        }
    }

    @SuppressLint("PrivateApi")
    private void setEnableWFD(WifiP2pManager wifiP2pManager, WifiP2pManager.Channel channel, boolean enable, WifiP2pManager.ActionListener listener) {
        try {
            //WifiP2pWfdInfo wifiP2pWfdInfo = new WifiP2pWfdInfo();
            Class clsWifiP2pWfdInfo = Class.forName("android.net.wifi.p2p.WifiP2pWfdInfo");
            Constructor ctorWifiP2pWfdInfo = clsWifiP2pWfdInfo.getConstructor();
            Object wifiP2pWfdInfo = ctorWifiP2pWfdInfo.newInstance();

            //wifiP2pWfdInfo.setWfdEnabled(true);
            Method mtdSetWfdEnabled = clsWifiP2pWfdInfo.getMethod("setWfdEnabled", boolean.class);
            mtdSetWfdEnabled.invoke(wifiP2pWfdInfo, enable);

            //wifiP2pWfdInfo.setDeviceType(WifiP2pWfdInfo.PRIMARY_SINK);
            Method mtdSetDeviceTypes = clsWifiP2pWfdInfo.getMethod("setDeviceType", int.class);
            mtdSetDeviceTypes.invoke(wifiP2pWfdInfo, 1);

            //wifiP2pWfdInfo.setSessionAvailable(true);
            Method mtdSetSessionAvailable = clsWifiP2pWfdInfo.getMethod("setSessionAvailable", boolean.class);
            mtdSetSessionAvailable.invoke(wifiP2pWfdInfo, enable);

            //wifiP2pWfdInfo.setMaxThroughput(MAX_THROUGHPUT);
            Method mtdSetMaxThroughput = clsWifiP2pWfdInfo.getMethod("setMaxThroughput", int.class);
            mtdSetMaxThroughput.invoke(wifiP2pWfdInfo, 50);

            if (listener != null) {
                Class clsWifiP2pManager = Class.forName("android.net.wifi.p2p.WifiP2pManager");
                Method methodSetWFDInfo = clsWifiP2pManager.getMethod("setWFDInfo",
                        WifiP2pManager.Channel.class, clsWifiP2pWfdInfo, WifiP2pManager.ActionListener.class);
                methodSetWFDInfo.invoke(wifiP2pManager, channel, wifiP2pWfdInfo, listener);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startDiscovery() {
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(mContext, Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                LogUtil.LogE("Successfully initialed peers discovery.");
                mIsStart = true;
            }

            @Override
            public void onFailure(int reason) {
                mIsStart = false;
                LogUtil.LogE("Failed to initial peers discovery.");
            }
        });
    }

    private void stopDiscovery() {
        wifiP2pManager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                LogUtil.LogE("onSuccess: Successfully stopped peers discovery.");
            }

            @Override
            public void onFailure(int reason) {
                LogUtil.LogE("Failed to stop peers discovery.");
                mIsStart = false;
            }
        });
//        mIsGroupFormed = false;
    }

    private static class MyActionListener implements WifiP2pManager.ActionListener {
        private final String mActionName;

        public MyActionListener(String actionName) {
            mActionName = actionName;
        }

        @Override
        public void onSuccess() {
            LogUtil.LogE( mActionName + " success");
        }

        @Override
        public void onFailure(int reason) {
            LogUtil.LogE( mActionName + " failed " + reason);
        }
    }
}
